package com.optionexplorer.data;

import java.util.ArrayList;
import java.util.logging.Logger;

import com.optionexplorer.util.NetUtils;
import com.optionexplorer.util.StringUtils;

public class YahooOptionQuotes {

	private static final Logger Log = Logger.getLogger(YahooOptionQuotes.class.getName());
	
	private String _stockQuote = null;
	private float _stockPrice = 0;
	private ArrayList<ArrayList<StockOption>> callOptionsMatrix = null;
	private ArrayList<ArrayList<StockOption>> putOptionsMatrix = null;
	
	public static String OPTIONS_BASE_URL = "http://finance.yahoo.com/q/op?s=";
	public static String YAHOO_BASE_URL = "http://finance.yahoo.com";
	private ArrayList<String> urlList = null;
	private ArrayList<String> expDateList = null;
		
	public YahooOptionQuotes(String str) {
		this._stockQuote = str;
	}	
	
	private void populatePageList() {
		
		urlList = new ArrayList<String>();
		expDateList = new ArrayList<String>();
		String baseUrl = OPTIONS_BASE_URL+this._stockQuote;
		String urlStr;
		String dateStr;
			
		//Now parse the first page for links to other pages.
		StringBuilder sb = NetUtils.getPageFromWeb(baseUrl);
		Log.info("Parsing for option links : " + baseUrl);
		int beginIndex = sb.indexOf("View By Expiration:");
		if (beginIndex < 0) {
			Log.severe("Can not find the expiration links");
			Log.severe(sb.toString());
			return;
		}
		
		int endIndex = sb.indexOf("<table", beginIndex);
		
		int index1 = sb.indexOf("<strong>", beginIndex);
		index1 += 8;
		int index2 = sb.indexOf("</strong>", index1);
		String expDate = sb.substring(index1, index2);
		
		// First page for the next immediate expiration
		urlList.add(baseUrl);
		expDateList.add(expDate);
		index1 = index2 + 4;
		
		// Now grab the remaining links
		while (index1 <= endIndex) {
			index1 = sb.indexOf("<a href=", index1);
			if (index1 < 0) {
				Log.info("No more links to parse. Exiting");
				return;
			}
			index1 += 9;
			index2 = sb.indexOf(">", index1);
			urlStr = sb.substring(index1, index2-1);
			index1 = index2 + 1;
			index2  = sb.indexOf("</a>", index1);
			dateStr = sb.substring(index1, index2);
			
			urlStr = urlStr.replaceAll("&amp;", "&");
			urlList.add(YAHOO_BASE_URL+urlStr);
			expDateList.add(dateStr);
			
			index1 = index2 + 5;			
		}
		
		//Look for ET: followed by <big><b> to get stock price
		String priceStr;
		index1 = sb.indexOf("ET");
		index1 = sb.indexOf("<big><b>", index1);
		if (index1 > 0) {
			index1 = index1 += 8;
			index2 = sb.indexOf("</b></big>", index1);
			priceStr = sb.substring(index1, index2);
			priceStr = StringUtils.stripHTML(priceStr);
			this._stockPrice = Float.parseFloat(priceStr);
		}
		
		Log.info("Stock Quote: " + this._stockQuote + " Price: " + this._stockPrice);
		Log.info(expDateList.toString());
		Log.info(urlList.toString());
	}
	
	/**
	 * Fills up the options matrix for a given stock ticker.
	 */
	public void populateOptionMatrix() {
		
		YahooOptionsOneMonth yom = null;
		callOptionsMatrix = new ArrayList<ArrayList<StockOption>>();
		putOptionsMatrix = new ArrayList<ArrayList<StockOption>>();
		
		SimpleOptionFilter sof = new SimpleOptionFilter();	
		
		// populate the page list first
		populatePageList();
		int count = urlList.size();
		
		int resultCount = 0;
		for (int i=0; i<count; i++) {
			yom = new YahooOptionsOneMonth(this._stockQuote,
										   urlList.get(i),
										   expDateList.get(i));
			yom.populateOptions();
			callOptionsMatrix.add(sof.filterData(yom.getCallOptionList()));
			putOptionsMatrix.add(sof.filterData(yom.getPutOptionList()));
		}
	}
	
	public ArrayList<ArrayList<StockOption>> getCallOptionsMatrix() {
		return callOptionsMatrix;
	}

	public ArrayList<ArrayList<StockOption>> getPutOptionsMatrix() {
		return putOptionsMatrix;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		YahooOptionQuotes yoq = new YahooOptionQuotes("CSTR");
		yoq.populateOptionMatrix();
	}
}
